package cn.kgc.springmvc.day02.controller;

import cn.kgc.springmvc.day02.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;

/**
 * @author 课工场
 * @date 2024/11/11
 * @description 解析springmvc框架对参数接收的处理
 * 1.  零散参数接收
 *      1.1  基本类型
 *          注意:  默认情况下  使用基本类型实现参数接收,请求时必须要携带形参列表中声明的数据
 *              如果出现形参列表中参数的名字和请求路径中的key不一致的情况 可以使用
 *                  @RequestParam("ag") 声明路径中的key和param的关联关系
 *              defaultValue = "20"  设置注解修饰的形参的默认值
 *      1.2 包装类型
 *           1.  形参的名字需要和请求路径中的key保持一致
 *           2.  形参列表中声明的参数没有传递 则直接赋值为null  不再抛出异常
 * 2.  对象类型接收
 *         1.  String
 *         2. 自定义类对象  User
 *         3. 数组
 * 3.  json格式数据
 *      前端   ->  {"username":"tom","age":20}
 *      后端   ->   springmvc中可以直接实现json格式参数的接收 同时实现数据类型转换
 *
 */
@Controller
@RequestMapping("param")
public class ParamController {
    /*
     *  方法中的形参列表
     *     int  id    形参的名字需要和请求路径中的key保持一致
     *    /param/m1?id=1&age=20
     *
     *     int  age  =  null     IllegalStateException
     *     Optional int parameter 'age' is present but cannot be translated into a null value due to being declared as a primitive type
     * */
    @RequestMapping("m1")
    public ModelAndView method1(int id, @RequestParam(value = "age", defaultValue = "20") int age) {

        System.out.println("id = " + id + ", age = " + age);

        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("info", "param");
        modelAndView.setViewName("main");

        return modelAndView;
    }


    /*
     *   参数列表中  接收的参数是包装类型参数           推荐
     *      1.  形参的名字需要和请求路径中的key保持一致
     *      2.  形参列表中声明的参数没有传递 则直接赋值为null  不再抛出异常
     * */
    @RequestMapping("m2")
    public ModelAndView method2(Integer id, @RequestParam(value = "age", defaultValue = "30")Integer age) {

        System.out.println("id = " + id + ", age = " + age);

        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("info", "param");
        modelAndView.setViewName("main");

        return modelAndView;
    }


    @RequestMapping("m3")
    public ModelAndView method3(Integer id, Integer age,String username,String password,Double weight) {

        System.out.println("id = " + id + ", age = " + age + ", username = " + username + ", password = " + password + ", weight = " + weight);
       //  封装数据   -> 对象  User

        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("info", "param");
        modelAndView.setViewName("main");

        return modelAndView;
    }

    /*
    *   形参列表中一自定义对象类型实现参数的接收
    *     注意:  请求路径中的key需要和对象中属性名保持一致, 否则对应的属性值为其默认值
    * */
    @RequestMapping("m4")
    public ModelAndView method4(User user) {
        //  封装数据   -> 对象  User
        System.out.println("user = " + user);
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("info", "param");
        modelAndView.setViewName("main");

        return modelAndView;
    }

    /*
    *   批量删除   ?ids=1&ids=2  ....
    *   Integer[]  可以直接实现封装
    *       List<Integer>       报错 无法实例化
            ArrayList<Integer>   没有异常  但是参数值为null
    * */

    @RequestMapping("m5")
    public ModelAndView method5(Integer[] ids) {

         if (ids!=null){
             for (Integer id : ids) {
                 System.out.println("id = " + id);
             }
         }

        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("info", "param");
        modelAndView.setViewName("main");
        return modelAndView;

    }


        /*
           ?id=1&username=tom&age=20   -> User user
        * {"username":"tom","age":20}   ->  json   ->  java
          后续如果前端传递的参数是以json格式  那么在参数接收时需要声明参数类型为json格式
        *  在方法的形参前 添加注解@RequestBody  表明前端传递的参数是json格式数据
        *
        * */
    @RequestMapping("m6")
    public ModelAndView method6(@RequestBody User user) {
        //  封装数据   -> 对象  User
        System.out.println("user = " + user);
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("info", "param");
        modelAndView.setViewName("main");

        return modelAndView;
    }


    // 后续在处理多个零散参数时 如果不想编写对应的dto 则直接可以使用map集合形式接收参数
    @RequestMapping("m7")
    public ModelAndView method7(@RequestBody Map<String,Object> ids) {
        //  封装数据   -> 对象  User

        System.out.println("ids = " + ids);

        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("info", "param");
        modelAndView.setViewName("main");

        return modelAndView;
    }


    //  通过json格式的数据   可是实现在参数列表中使用list集合进行参数接收
    @RequestMapping("m8")
    public ModelAndView method8(@RequestBody List<Integer> ids) {
        //  封装数据   -> 对象  User

       if (ids!=null){
           ids.forEach(System.out::println);
       }

        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("info", "param");
        modelAndView.setViewName("main");

        return modelAndView;
    }


    //  springmvc环境下  依然可以使用传统的方式 实现参数接收
    // request response 在方法调用时 会自动传入 不需要手动维护
    @RequestMapping("m9")
    public ModelAndView method9(HttpServletRequest request, HttpServletResponse response) {

        // 获取参数
        String username = request.getParameter("username");
        System.out.println("username = " + username);
        String password = request.getParameter("password");
        System.out.println("password = " + password);


        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("info", "param");
        modelAndView.setViewName("main");

        return modelAndView;
    }

}
